<?php

namespace App\Console\Commands;

use App\Library\Logger;
use App\Models\CityModel;
use App\Models\Dept\Zone;
use App\Models\DeptModel;
use Illuminate\Console\Command;

/**
 * 生成部门管辖区域
 * 西南: 四川、云南、重庆、贵州
 * 宁德: 福建
 * 华东: 江苏、浙江、上海、北京
 * 华南：广东、广西
 * 华中：湖北、湖南、江西、山东、河南、山西、安徽、山西、河北
 */
class GenerateDeptZones extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'generate:dept_zones';
    private $logger;
    private $deptZones;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '生成部门区域数据';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
        $this->logger = new Logger('generate/dept_zone');
        $this->deptZones = [
            '西南' => ['四川', '云南', '重庆', '贵州'],
            '宁德' => ['福建'],
            '华东' => ['江苏', '浙江', '上海', '北京'],
            '华南' => ['广东', '广西'],
            '华中' => ['湖北', '湖南', '江西', '山东', '河南', '山西', '安徽', '山西', '河北']
        ];
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $bench = new \Ubench();
        $bench->start();

        Zone::query()->truncate();
        $cities = $this->getCities();
        foreach ($cities as $deptId => $cityIds) {
            foreach ($cityIds as $cityId) {
                $this->logger->info("insert data: {$deptId} -> {$cityId}");
                $zone = new Zone();
                $zone->fill([
                    'dept_id' => $deptId,
                    'city_id' => $cityId
                ]);
                $zone->saveOrFail();
            }
        }

        $bench->end();
        $this->logger->debug("time used: " . $bench->getTime());
        $this->logger->debug("memory used: " . $bench->getMemoryUsage());
    }

    private function getCities()
    {
        $allZones = [];
        foreach ($this->deptZones as $zones) {
            $allZones = array_merge($zones, $allZones);
        }
        $allZones = array_unique($allZones);
        $depts = array_keys($this->deptZones);
        $zoneData = CityModel::query()
            ->select(['id', 'name'])
            ->where(function ($query) use ($allZones) {
                foreach ($allZones as $zone) {
                    $query->orWhere(function ($query) use ($zone) {
                        $query->where('name', 'like', "%{$zone}%")
                            ->where('pid', 0)
                            ->where('level', 1);
                    });
                }
            })
            ->get()
            ->toArray();
        $result = [];
        foreach ($depts as $dept) {
            $deptData = DeptModel::query()->where('name', 'like', "%{$dept}%")->first();
            if (empty($deptData)) {
                continue;
            }
            $deptId = $deptData->id;
            $zones = $this->deptZones[$dept] ?? [];
            if (empty($zones)) {
                continue;
            }
            $itemZoneIds = [];
            foreach ($zoneData as $itemZone) {
                foreach ($zones as $zone) {
                    if (strrpos($itemZone['name'], $zone) !== false) {
                        $itemZoneIds[] = $itemZone['id'];
                    }
                }
            }
            $result[$deptId] = $itemZoneIds;
        }
        return $result;
    }
}
